use std::time::{Instant};
use log::info;
use rpc::{RpcChannel, RpcContext, RpcResult};
use rpc::bootstrap::BootstrapBuilder;
use rpc_client::client::RpcClientBuilder;
use rpc_derive::{router, rpc_router, rpc_service, service};
use rpc_server::server::RpcServerBuilder;

// #[tokio::test]
pub async fn server_start() -> RpcResult<()> {
    let bootstrap = BootstrapBuilder::new()
        .router("/world", router!(world))
        ;
    let _ = RpcServerBuilder::new(bootstrap, 8888)
        .build().start_server().await;
    Ok(())
}

// #[tokio::test]
async fn client_test() -> RpcResult<()> {
    let bootstrap = BootstrapBuilder::new()
        .build();
    let mut channel = RpcClientBuilder::new(bootstrap, "localhost:8888")
        .set_current_codec_type("json")
        .build().connection().await?;

    let mut hello_service = service!(channel.context.clone(), HelloService);

    let now = Instant::now();
    for i in 0..1000 {
        let data = format!("hello {}", i);
        let result = hello_service.world(&mut channel, data).await?;
        // info!("call result: {}", result);
    }
    let time = now.elapsed();
    info!("call time: {:?}", time.as_millis());

    Ok(())
}

#[rpc_router]
fn world(context: &mut RpcContext, value: String) -> String {
    let mut result = value;
    result.push_str(" ok ");
    result
}


#[rpc_service]
#[async_trait::async_trait]
trait HelloService {

    // #[path(name="/hello", timeout=60)]
    #[path = "/world"]
    async fn world(&mut self, channel: &mut impl RpcChannel, data: String) -> RpcResult<String>;
}